import type { DirectiveBinding, VNode } from 'vue'

interface CountdownElement extends HTMLElement {
  _countdownTimer?: number
  _originalText?: string
  _countdownKey?: string
  _isCountingDown?: boolean
  disabled: boolean
}

interface CountdownBinding {
  seconds: number
  key?: string
  text?: string
}

// 本地存储键前缀
const STORAGE_PREFIX = 'countdown_'

// 获取存储键
function getStorageKey(key: string): string {
  return STORAGE_PREFIX + key
}

// 保存倒计时状态到本地存储
function saveCountdownState(key: string, endTime: number): void {
  localStorage.setItem(getStorageKey(key), endTime.toString())
}

// 从本地存储获取倒计时状态
function getCountdownState(key: string): number | null {
  const stored = localStorage.getItem(getStorageKey(key))
  return stored ? parseInt(stored, 10) : null
}

// 清除倒计时状态
function clearCountdownState(key: string): void {
  localStorage.removeItem(getStorageKey(key))
}

// 检查倒计时是否已过期
function isCountdownExpired(endTime: number): boolean {
  return Date.now() >= endTime
}

// 计算剩余秒数
function getRemainingSeconds(endTime: number): number {
  return Math.max(0, Math.ceil((endTime - Date.now()) / 1000))
}

// 更新按钮状态
function updateButtonState(el: CountdownElement, remainingSeconds: number, originalText: string, customText?: string): void {
  if (remainingSeconds > 0) {
    el.disabled = true
    el.style.opacity = '0.6'
    el.style.cursor = 'not-allowed'
    const displayText = customText ? customText.replace('{seconds}', remainingSeconds.toString()) : `${remainingSeconds}秒后重试`
    el.textContent = displayText
    el._isCountingDown = true
  } else {
    el.disabled = false
    el.style.opacity = ''
    el.style.cursor = ''
    el.textContent = originalText
    el._isCountingDown = false
  }
}

// 开始倒计时
function startCountdown(el: CountdownElement, seconds: number, key: string, originalText: string, customText?: string): void {
  const endTime = Date.now() + seconds * 1000
  saveCountdownState(key, endTime)
  
  const updateTimer = () => {
    const remaining = getRemainingSeconds(endTime)
    updateButtonState(el, remaining, originalText, customText)
    
    if (remaining > 0) {
      el._countdownTimer = window.setTimeout(updateTimer, 1000)
    } else {
      clearCountdownState(key)
      if (el._countdownTimer) {
        clearTimeout(el._countdownTimer)
        el._countdownTimer = undefined
      }
    }
  }
  
  updateTimer()
}

// 恢复倒计时状态
function restoreCountdown(el: CountdownElement, key: string, originalText: string, customText?: string): void {
  const endTime = getCountdownState(key)
  if (!endTime) return
  
  if (isCountdownExpired(endTime)) {
    clearCountdownState(key)
    updateButtonState(el, 0, originalText, customText)
    return
  }
  
  const remaining = getRemainingSeconds(endTime)
  updateButtonState(el, remaining, originalText, customText)
  
  const updateTimer = () => {
    const remaining = getRemainingSeconds(endTime)
    updateButtonState(el, remaining, originalText, customText)
    
    if (remaining > 0) {
      el._countdownTimer = window.setTimeout(updateTimer, 1000)
    } else {
      clearCountdownState(key)
      if (el._countdownTimer) {
        clearTimeout(el._countdownTimer)
        el._countdownTimer = undefined
      }
    }
  }
  
  if (remaining > 0) {
    el._countdownTimer = window.setTimeout(updateTimer, 1000)
  }
}

// 清理定时器
function cleanup(el: CountdownElement): void {
  if (el._countdownTimer) {
    clearTimeout(el._countdownTimer)
    el._countdownTimer = undefined
  }
}

// 点击事件处理
function handleClick(el: CountdownElement, binding: DirectiveBinding<CountdownBinding>): void {
  if (el._isCountingDown) return
  
  const { seconds, key, text } = binding.value
  const countdownKey = key || `btn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  const originalText = el._originalText || el.textContent || ''
  
  el._countdownKey = countdownKey
  startCountdown(el, seconds, countdownKey, originalText, text)
}

export const countdown = {
  mounted(el: CountdownElement, binding: DirectiveBinding<CountdownBinding>, vnode: VNode) {
    // 保存原始文本
    el._originalText = el.textContent || ''
    
    const { key } = binding.value
    if (key) {
      el._countdownKey = key
      // 恢复倒计时状态
      restoreCountdown(el, key, el._originalText, binding.value.text)
    }
    
    // 添加点击事件监听器
    const clickHandler = () => handleClick(el, binding)
    el.addEventListener('click', clickHandler)
    
    // 保存事件处理器引用以便后续清理
    ;(el as any)._clickHandler = clickHandler
  },
  
  updated(el: CountdownElement, binding: DirectiveBinding<CountdownBinding>) {
    // 如果绑定值发生变化，更新相关状态
    const { key, text } = binding.value
    if (key && key !== el._countdownKey) {
      cleanup(el)
      el._countdownKey = key
      restoreCountdown(el, key, el._originalText || '', text)
    }
  },
  
  beforeUnmount(el: CountdownElement) {
    // 清理定时器和事件监听器
    cleanup(el)
    if ((el as any)._clickHandler) {
      el.removeEventListener('click', (el as any)._clickHandler)
    }
  }
}

export default countdown
